/*
 * @(#)ToString.java, 2009-2-22
 *
 * Copyright 2009 SuperV System Integration CO., LTD. All rights reserved.
 */
package org.lex.utils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;

/**
 * 
 * 
 * @author Liu Er Xiao
 * @version 1.0, 2009-2-22
 */
public class ToString2 {
	private static final Object[] EMPTY_ARGS = new Object[0];
	private static final Comparator<Method> METHOD_COMPARATOR = new Comparator<Method>() {
		public int compare(Method o1, Method o2) {
			return o1.getName().compareTo(o2.getName());
		}
	};

	public static String beanToString(Object bean) {
		if (null == bean)
			return "null";
		StringBuilder buf = new StringBuilder();
		Class<?> clz = bean.getClass();
		buf.append('[').append(clz.getSimpleName());
		buf.append(": ");
		Method[] methods = clz.getMethods();
		Arrays.sort(methods, METHOD_COMPARATOR);
		for (Method m : methods) {
			String name = m.getName();
			Class<?>[] args = m.getParameterTypes();
			if (name.startsWith("get") && 0 == args.length && Class.class != m.getReturnType()) {
				name = name.substring(3);
				buf.append(Character.toLowerCase(name.charAt(0)));
				buf.append(name.substring(1));
				buf.append('=');
				Object value = null;
				try {
					value = m.invoke(bean, EMPTY_ARGS);
				} catch (Exception e) {
					e.printStackTrace();
					value = "ERROR: " + e.getMessage();
				}
				appendValue(value, buf);
				buf.append(", ");
			}
		}
		buf.setLength(buf.length() - 2);
		buf.append(']');
		return buf.toString();
	}

	private static void appendValue(Object value, StringBuilder buf) {
		if (null == value) {
			buf.append("null");
			return;
		}
		Class<?> clz = value.getClass();
		if (clz.isPrimitive()) {
			buf.append(String.valueOf(value));
			return;
		} else if (clz.isArray()) {
			int length = Array.getLength(value);
			if (0 != length) {
				Object e = null;
				for (int i = 0; i < length && null == e; i++) {
					e = Array.get(value, i);
				}
				if (null != e) {
					buf.append(e.getClass().getSimpleName());
				}
			}
			buf.append('[').append(length).append(']');
			return;
		} else if (Collection.class.isInstance(value)) {
			Collection c = (Collection) value;
			int size = c.size();
			if (0 != size) {
				Object e = null;
				for (Iterator i = c.iterator(); i.hasNext() && null == e;) {
					e = i.next();
				}
				if (null != e) {
					buf.append(e.getClass().getSimpleName());
				}
			}
			buf.append('[').append(size).append(']');
			return;
		} else {
			buf.append(String.valueOf(value));
		}
	}

	public static String exceptionToString(Throwable e) {
		StringWriter out = new StringWriter();
		PrintWriter pw = new PrintWriter(out, true);
		e.printStackTrace(pw);
		pw.flush();
		return out.toString();
	}
}
